import type { FormItemDto } from './types'
import elements from './Elements'
import type { JSX } from 'vue/jsx-runtime'
import { getChannelList, getCompanyList } from '@/api/company'
import type { CompanyDto } from '@/api/company/types'
import { CompanyAuditStatusCnEnum, DeptTypeCnEnum, PlatformTypeCnEnum } from '@/const/enum'
import { getSaleList } from '@/api/sale'
import { getDaliyInsuranceCompanyList, getPeriodInsuranceCompanyList } from '@/api/insurance/company'
import type { ServeCompanyDto } from '@/api/dispatch/type'
import { getServeCompanyList } from '@/api/dispatch'
import { getReceiptList } from '@/api/customer'
import { getDepartmentList, getDeptList, getMemberType, getRoleList, getSystemUserList } from '@/api/system'
import { getInsCompanyRule, getInsureCompanyInfoList, getInsureCompanyList } from '@/api/insCompany/index'
import type { SaleDto } from '@/api/sale/types'
import type { TreeDto } from '@/api/types'
import type { AnyObject } from '@/types'
import { shake } from '@/utils/util'
import { queryEmailRuleList } from '@/api/emailConfig'
import { getDailyIndustryList } from '@/api/insurance/daily'
import { getInsureCompanyPlans } from '@/api/insureEnsurePlan'

function createOptions(source: AnyObject[], {label, value}: {label: string, value: string}): TreeDto[] {
    return source.map((item) => {
        if (item?.children?.length) {
            return {
                label: item[label as keyof typeof item],
                value: item[value as keyof typeof item],
                children: createOptions(item.children, {
                    label,
                    value
                })
            }
        }
        return {
            label: item[label as keyof typeof item],
            value: item[value as keyof typeof item]
        }
    })
}

export async function getFormOptions(data: FormItemDto) {
    if (data.options) {
        return
    }
    if (data.callback?.method) {
        data.options = []
        data.options = await data.callback?.method?.('')
        return 
    }
    // 可选项加载
    switch (data.optionsType) {
    case 'company':
        data.params = data.params || {}
        data.params.method = async (ev: string) => {
            if (!ev) return []
            shake(async () => {
                const options = await getCompanyList({
                    companyName: ev,
                    limit: 10
                })
                data.options = options.map((item: CompanyDto) => {
                    if (data.element === 'autoComplete') {
                        return {
                            label: item.companyName,
                            value: item.companyName
                        }
                    }
                    return {
                        label: `${item.companyName} (${CompanyAuditStatusCnEnum[item.auditStatus]})`,
                        value: item.id
                    }
                })
            })
        }
        return
    case 'serveCompany':
        data.params = data.params || {}
        data.params.method = async (ev:string) => { 
            if (!ev) return []
            const res = await getServeCompanyList({ serveCompanyName: ev })
            data.options = res.map((item: ServeCompanyDto) => {
                if (data.element === 'autoComplete') {
                    return {
                        label: item.serveCompanyName,
                        value: item.serveCompanyName
                    }
                }
                return {
                    label: item.serveCompanyName,
                    value: item.id
                }
            })
        }
        return
    case 'channel':
        data.options = (await getChannelList()).map(item => ({
            label: item.name,
            value: item.id
        }))
        return
    case 'sale':
        data.params = data.params || {}
        data.params.method = async (ev: string) => {
            if (!ev) return []
            const options = await getSaleList({
                salesName: ev,
                auditStatus: 1,
                limit: 10
            })
            data.options = options.map((item: SaleDto) => {
                return {
                    label: item.saleName,
                    value: item.saleId
                }
            })
        }
        return
    case 'saleDept':
        data.options = (await getDeptList({
            platform: PlatformTypeCnEnum.新运营平台,
            type: DeptTypeCnEnum.商务,
        })).map(item => ({
            label: item.deptName,
            value: item.deptId
        }))
        return
    case 'saleList':
        data.options = (await getSaleList()).map(item => ({
            label: item.saleName,
            value: item.saleId
        }))
        return
    case 'insurCompany':
        data.options = (await getPeriodInsuranceCompanyList()).map(item => ({
            label: item.dictLabel,
            value: item.dictValue
        }))
        return
    case 'insureCompany':
        data.options = (await getInsureCompanyInfoList()).map(item => ({
            label: item.name,
            value: item.code
        }))
        return
    case 'insureCompanyId':
        data.options = (await getInsureCompanyInfoList()).map(item => ({
            label: item.name,
            value: item.id
        }))
        return
    case 'daliyInsuranceCompany':
        data.options = (await getDaliyInsuranceCompanyList()).map(item => ({
            label: item.dictLabel,
            value: item.dictValue
        }))
        return
    case 'receipt':
        data.options = (await getReceiptList({
            pageSize: 999,
            pageNum: 1
        })).list.map(item => ({
            label: item.bankName,
            value: item.id
        }))
        return 
    case 'sex':
        data.options = [
            { label: '男', value: '1' },
            { label: '女', value: '2' },
        ]
        return
    case 'department':
        data.options = createOptions((await getDepartmentList()), {
            label: 'label',
            value: 'id'
        })
        return
    case 'memberType':
        data.options = (await getMemberType()).map(item => ({
            label: item.postName,
            value: item.postId
        }))
        return
    case 'role':
        data.options = (await getRoleList({
            pageNum: 1,
            pageSize: 999,
        })).rows.map(item => ({
            label: item.roleName,
            value: item.roleId
        }))
        return
    case 'insureCompanyRule': // 保司规则列表
        data.options = (await getInsCompanyRule()).map(item => ({
            label: item.key,
            value: item.value
        }))
        return
    case 'emailRule':
        data.options = (await queryEmailRuleList({})).map(item => ({
            label: item.ruleName,
            value: item.id
        }))
        return
    case 'insureCompanyList': // 保司列表
        data.options = (await getInsureCompanyList()).map(item => ({
            label: item.key,
            value: item.value
        }))
        return
    case 'dailyIndustryList':
        data.options = (await getDailyIndustryList({
            ...data.params.optionsParams
        })).rows.map(item => ({
            label: item.industryName,
            value: item.id
        }))
        return
    case 'insurePlanList': // 保司方案列表
        data.options = (await getInsureCompanyPlans({
            ...data.params.optionsParams
        })).map(item => ({
            label: item.key,
            value: item.value
        }))
        return
    }

}

export default function (config: FormItemDto) {
    const els = {
        ...elements,
    } as {
        [key: string]: (data: FormItemDto) => JSX.Element
    }

    // if (config.element === 'autoComplete' && !config.params?.method) {
    //     config.params.method = (value: string, cb: (options: any[]) => void) => {
    //         cb(config.options?.filter(text => (text.value as string).includes(value)) ?? [])
    //     }
    // }

    (async () => {
        if (config.options) {
            return
        }
        await getFormOptions(config)
    })()

    typeof config.callback?.init === 'function' && config.callback.init()
    setTimeout(() => {
        typeof config.callback?.load === 'function' && config.callback.load()
    }, 600)
    return els[config.element]?.(config) ?? <div></div>
}